package com.chentf.nio.c3;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.Iterator;
import java.util.Set;

/**
 * @author chentengfei
 * @desc 多路复用select服务端
 * @date 2022-05-07 20:21:21
 */
public class SelectServer02 {
    public static void main(String[] args) {
        ByteBuffer byteBuffer = ByteBuffer.allocate(16);
        //获得服务器通道
        try (ServerSocketChannel ssc = ServerSocketChannel.open()){
            ssc.bind(new InetSocketAddress(8080));
            //创建选择器
            Selector selector = Selector.open();
            //通道必须设置成非阻塞模式
            ssc.configureBlocking(false);
            //将通道注册到选择器中,并设置感兴趣的事件
            ssc.register(selector, SelectionKey.OP_ACCEPT);
            while (true){
                //若没有事件就绪,线程会被阻塞,反之不会阻塞,从而避免了CPU空转
                //返回值为就绪的事件个数
                int ready = selector.select();
                //int ready2 = selector.selectNow();
                System.out.println("selector ready counts:"+ready);
                //获取所有事件
                Set<SelectionKey> selectionKeys = selector.selectedKeys();
                //使用迭代器遍历事件
                Iterator<SelectionKey> iterator = selectionKeys.iterator();
                while (iterator.hasNext()){
                    SelectionKey key = iterator.next();
                    //判断key的类型
                    if(key.isAcceptable()){
                        //获得key对应的channel
                        ServerSocketChannel channel =(ServerSocketChannel) key.channel();
                        System.out.println("before accepting...");
                        //获取连接并处理,而且是必须处理,否则需要取消
                        SocketChannel socketChannel = channel.accept();
                        System.out.println("after accepting...");
                        //处理完成后移除
                        iterator.remove();
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
